﻿#pragma once

#include "../../Shared/Enums.h"
#include <string>
#include <vector>
#include "../../tangible_event.h"
#include "../../vectorhelper.h"
#include "../../disposable_interface.h"

using namespace Client::MirGraphics;
using namespace Client::MirSounds;
using namespace SlimDX;
using namespace SlimDX::Direct3D9;

namespace Client::MirControls
{
    class MirControl : public Disposable
    {
    private:
        bool GrayScale = false;
        bool Blending = false;
        float BlendingRate = 0;
        BlendMode BlendMode = static_cast<BlendMode>(0);
        std::vector<MirControl*> Controls;
        bool IsDisposed = false;

    public:
        static MirControl *ActiveControl;
        static MirControl *MouseControl;

        virtual ~MirControl()
        {
            delete _backColour;
            delete BorderRectangle;
            delete _borderColour;
            delete ControlTexture;
            delete TextureSize;
            delete _foreColour;
            delete _location;
            delete _movePoint;
            delete _parent;
            delete _size;
        }

        virtual Point *getDisplayLocation() const;
        Rectangle *getDisplayRectangle() const;

        bool getGrayScale() const;
        void setGrayScale(bool value);
        bool getBlending() const;
        void setBlending(bool value);
        float getBlendingRate() const;
        void setBlendingRate(float value);
        BlendMode getBlendMode() const;
        void setBlendMode(BlendMode value);

        #pragma region Back Colour
    private:
        Color *_backColour;
    public:
        Color *getBackColour() const;
        void setBackColour(Color *value);
        TangibleEvent<EventHandler> *BackColourChanged = new TangibleEvent<EventHandler>();
    protected:
        virtual void OnBackColourChanged();
        #pragma endregion

        #pragma region Border
        Rectangle *BorderRectangle;
    private:
        bool _border = false;
    protected:
        std::vector<Vector2*> _borderInfo;
        virtual std::vector<Vector2*> getBorderInfo() const;
    public:
        virtual bool getBorder() const;
        virtual void setBorder(bool value);
        TangibleEvent<EventHandler> *BorderChanged = new TangibleEvent<EventHandler>();
    private:
        void OnBorderChanged();
        #pragma endregion

        #pragma region Border Colour
        Color *_borderColour;
    public:
        Color *getBorderColour() const;
        void setBorderColour(Color *value);
        TangibleEvent<EventHandler> *BorderColourChanged = new TangibleEvent<EventHandler>();
    private:
        void OnBorderColourChanged();
        #pragma endregion

        #pragma region Control Texture
    public:
        long long CleanTime = 0;
    protected:
        Texture *ControlTexture;
        bool TextureValid = false;
    private:
        bool _drawControlTexture = false;
    protected:
        Size *TextureSize;
    public:
        bool getDrawControlTexture() const;
        void setDrawControlTexture(bool value);
    protected:
        virtual void CreateTexture();

    public:
        void DisposeTexture();
        #pragma endregion

        #pragma region Controls
        std::vector<MirControl*> getControls() const;
        void setControls(const std::vector<MirControl*> &value);
//C# TO C++ CONVERTER TODO TASK: This event cannot be converted to C++:
//        public event EventHandler ControlAdded, ControlRemoved;
    private:
        void AddControl(MirControl *control);
    public:
        void InsertControl(int index, MirControl *control);
    private:
        void RemoveControl(MirControl *control);
        void OnControlAdded();
        void OnControlRemoved();
        #pragma endregion

        #pragma region Enabled
        bool _enabled = false;
    public:
        public:
        bool getEnabled() const;
        public:
        void setEnabled(bool value);
        TangibleEvent<EventHandler> *EnabledChanged = new TangibleEvent<EventHandler>();
    protected:
        virtual void OnEnabledChanged();
        #pragma endregion

        #pragma region Events
        bool HasShown = false;
//C# TO C++ CONVERTER TODO TASK: This event cannot be converted to C++:
//        public event EventHandler Click, DoubleClick, BeforeDraw, AfterDraw, MouseEnter, MouseLeave, Shown, BeforeShown, Disposing;
//C# TO C++ CONVERTER TODO TASK: This event cannot be converted to C++:
//        public event MouseEventHandler MouseWheel,MouseMove, MouseDown, MouseUp;
//C# TO C++ CONVERTER TODO TASK: This event cannot be converted to C++:
//        public event KeyEventHandler KeyDown, KeyUp;
//C# TO C++ CONVERTER TODO TASK: This event cannot be converted to C++:
//        public event KeyPressEventHandler KeyPress;
        #pragma endregion

        #pragma region Fore Colour
    private:
        Color *_foreColour;
    public:
        Color *getForeColour() const;
        void setForeColour(Color *value);
        TangibleEvent<EventHandler> *ForeColourChanged = new TangibleEvent<EventHandler>();
    protected:
        virtual void OnForeColourChanged();
        #pragma endregion

        #pragma region Location
    private:
        Point *_location;
    public:
        Point *getLocation() const;
        void setLocation(Point *value);
        TangibleEvent<EventHandler> *LocationChanged = new TangibleEvent<EventHandler>();
    protected:
        virtual void OnLocationChanged();
        #pragma endregion

        #pragma region Hint
    private:
        std::string _hint;
    public:
        std::string getHint() const;
        void setHint(const std::string &value);
        TangibleEvent<EventHandler> *HintChanged = new TangibleEvent<EventHandler>();
    private:
        void OnHintChanged(EventArgs *e);
        #pragma endregion

        #pragma region Modal
        bool _modal = false;
    public:
        bool getModal() const;
        void setModal(bool value);
        TangibleEvent<EventHandler> *ModalChanged = new TangibleEvent<EventHandler>();
    private:
        void OnModalChanged();
        #pragma endregion

        #pragma region Movable
    protected:
        bool Moving = false;
    private:
        bool _movable = false;
        Point *_movePoint;

    public:
        bool getMovable() const;
        void setMovable(bool value);

        TangibleEvent<EventHandler> *MovableChanged = new TangibleEvent<EventHandler>();
//C# TO C++ CONVERTER TODO TASK: This event cannot be converted to C++:
//        public event MouseEventHandler OnMoving;

    private:
        void OnMovableChanged();
        #pragma endregion

        #pragma region Not Control
        bool _notControl = false;
    public:
        private:
        bool getNotControl() const;
        public:
        void setNotControl(bool value);
        TangibleEvent<EventHandler> *NotControlChanged = new TangibleEvent<EventHandler>();
    private:
        void OnNotControlChanged();
        #pragma endregion

        #pragma region Opacity
        float _opacity = 0;
    public:
        float getOpacity() const;
        void setOpacity(float value);
        TangibleEvent<EventHandler> *OpacityChanged = new TangibleEvent<EventHandler>();
    private:
        void OnOpacityChanged();
        #pragma endregion

        #pragma region Parent
        MirControl *_parent;
    public:
        MirControl *getParent() const;
        void setParent(MirControl *value);
        TangibleEvent<EventHandler> *ParentChanged = new TangibleEvent<EventHandler>();
    protected:
        virtual void OnParentChanged();
        #pragma endregion

        #pragma region Size

// ReSharper disable InconsistentNaming
        Size *_size;
// ReSharper restore InconsistentNaming

    public:
        virtual Size *getSize() const;
        virtual void setSize(Size *value);

        virtual Size *getTrueSize() const;

        TangibleEvent<EventHandler> *SizeChanged = new TangibleEvent<EventHandler>();
    protected:
        virtual void OnSizeChanged();
        #pragma endregion

        #pragma region Sound
    private:
        int _sound = 0;
    public:
        int getSound() const;
        void setSound(int value);
        TangibleEvent<EventHandler> *SoundChanged = new TangibleEvent<EventHandler>();
    private:
        void OnSoundChanged();
        #pragma endregion

        #pragma region Sort
        bool _sort = false;
    public:
        bool getSort() const;
        void setSort(bool value);
        TangibleEvent<EventHandler> *SortChanged = new TangibleEvent<EventHandler>();
    private:
        void OnSortChanged();
    public:
        void TrySort();
        #pragma endregion

        #pragma region Visible
    private:
        bool _visible = false;
    public:
        virtual bool getVisible() const;
        virtual void setVisible(bool value);
        TangibleEvent<EventHandler> *VisibleChanged = new TangibleEvent<EventHandler>();
    protected:
        virtual void OnVisibleChanged();
        void OnBeforeShown();
        void OnShown();
        #pragma endregion

        #pragma region MultiLine

    public:
        virtual void MultiLine();

        #pragma endregion

        #pragma region Positions

    protected:
        Point *getCenter() const;

        Point *getLeft() const;

        Point *getTop() const;

        Point *getRight() const;

        Point *getBottom() const;

        Point *getTopLeft() const;

        Point *getTopRight() const;

        Point *getBottomRight() const;

        Point *getBottomLeft() const;

        #pragma endregion


    public:
        void BringToFront();

        MirControl();

        virtual void Show();

        virtual void Hide();

        virtual void Draw();

    protected:
        virtual void BeforeDrawControl();
        virtual void DrawControl();
        void DrawChildControls();
        virtual void DrawBorder();
        void AfterDrawControl();

        virtual void Deactivate();
        virtual void Dehighlight();
        virtual void Activate();
        virtual void Highlight();

    public:
        virtual bool IsMouseOver(Point *p);
    protected:
        virtual void OnMouseEnter();
        virtual void OnMouseLeave();
    public:
        virtual void OnMouseClick(MouseEventArgs *e);
        virtual void OnMouseDoubleClick(MouseEventArgs *e);
        void InvokeMouseClick(EventArgs *e);
        void InvokeMouseDoubleClick(EventArgs *e);
        virtual void OnMouseMove(MouseEventArgs *e);
        virtual void OnMouseDown(MouseEventArgs *e);
        virtual void OnMouseUp(MouseEventArgs *e);
        virtual void OnMouseWheel(MouseEventArgs *e);
        virtual void OnKeyPress(KeyPressEventArgs *e);
        virtual void OnKeyDown(KeyEventArgs *e);
        virtual void OnKeyUp(KeyEventArgs *e);

        virtual void Redraw();

        #pragma region Font
        virtual System::Drawing::Font *ScaleFont(System::Drawing::Font *font);
        #pragma endregion

        #pragma region Disposable
        bool isDisposed() const;
        void setDisposed(bool value);

        void Dispose() override;

    protected:
        virtual void Dispose(bool disposing);
        #pragma endregion



    };
}
